package com.woniuxy.shiro;

import com.woniuxy.entity.RbacManager;
import com.woniuxy.service.RbacManagerService;
import com.woniuxy.service.RbacPermService;
import com.woniuxy.service.RbacRoleService;
import com.woniuxy.utils.JWTUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import java.util.Set;

/*
 * 自定义域:校验token的有效性
 * */
@Configuration
public class MyRealm extends AuthorizingRealm {
    RbacManagerService rbacManagerService;
    RbacRoleService rbacRoleService;
    RbacPermService rbacPermService;
    @Override
    public boolean supports(AuthenticationToken token) {
        //这里是shiro底层的的问题，我们要手动重写底层的判断逻辑
        return token instanceof MyJsonWebToken;
    }

    /*授权
     *参数：pricipals JWT的token
     * */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //通过下面的认证方法SimpAuthenticationInfo对象中的凭证获取到token的值
        String token = principals.getPrimaryPrincipal() + "";
        String username = JWTUtils.getUsername(token);
        //使用username去数据库查出你的所有的角色和权限并封装到SimplAuthorizationInfo中
       //查询当前登录的subject用户的角色
        String roleName = rbacRoleService.findByRbacManager(username);
        SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addRole(roleName);
        //查询当前登录的subject权限集合
        Set<String> perm =rbacPermService.findByUsername(username);
        simpleAuthorizationInfo.setStringPermissions(perm);
        return simpleAuthorizationInfo;
    }

    /*
     * 认证
     *jwtToken  JWT的token昨天传入的是UsernamePasswordToken
     * */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken jwtToken) throws AuthenticationException {
//通过token获取我们自定义的MyJsonWebToken
        String token = jwtToken.getPrincipal() + "";

        //c从token中拿出用户名 后面吹篡改token的body值，来尝试，看能够获取到usernama  不先校验的情况
        String username = JWTUtils.getUsername(token);
        if ("".equals(username)) {
            throw new AuthenticationException("用户信息不对!");
        }
        //调用service，查询数据库，获取用户信息
        RbacManager user = rbacManagerService.findOne(username);
        boolean verify = JWTUtils.verify(token, username, user.getPassword());
        if (verify) {
            return new SimpleAuthenticationInfo(token, token, "myRealm");
        }
        return null;
    }
}
